package com.mzm.util.persistency;

import java.util.LinkedList;
import java.util.Queue;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;

/**
 * An ID generator that is based on a DB table. This generator uses an ID buffer
 * in order to decrease the number of required queries.
 * 
 * @author Daniel Orr
 * 
 */
public abstract class DbTableIdGenerator {

	@Resource
	private JdbcTemplate jdbcTemplate;

	private Queue<Long> cachedValues = new LinkedList<Long>();

	private String tableName;

	private int allocationSize = 20;

	
	public DbTableIdGenerator(String tableName) {
		this.tableName = tableName;
	}

	public DbTableIdGenerator(String tableName, int allocationSize) {
		this.tableName = tableName;
		this.allocationSize = allocationSize;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public int getAllocationSize() {
		return allocationSize;
	}

	public void setAllocationSize(int allocationSize) {
		this.allocationSize = allocationSize;
	}

	/**
	 * 
	 * @return
	 */
	public synchronized Long getNextId() {
		if (cachedValues.isEmpty()) {
			fillQueue();
		}
		return cachedValues.poll();
	}

	private void fillQueue() {
		jdbcTemplate.update("UPDATE\n" + "    " + tableName + "\n" + "SET\n"
				+ "    GEN_VALUE = GEN_VALUE+?\n" + "WHERE\n" + "    GEN_KEY = 'K'", new Integer(
				allocationSize));

		long val = jdbcTemplate.queryForInt("select GEN_VALUE from " + tableName
				+ " where GEN_KEY='K'");
		long oldPos = val - allocationSize;
		for (int i = 0; i < allocationSize; i++) {
			cachedValues.offer(oldPos + i + 1);
		}
	}
}
